// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#include <ktest/ktest.h>

#include <nebula/array/array_nested.h>
#include <nebula/array/util.h>
#include <nebula/core/pretty_print.h>
#include <nebula/testing/ktest_util.h>
#include <nebula/types/type_fwd.h>

namespace nebula {


    // ----------------------------------------------------------------------
    // List-view array tests

    namespace {

        class TestListViewArray : public ::testing::Test {
        public:
            std::shared_ptr<Array> string_values;
            std::shared_ptr<Array> int32_values;
            std::shared_ptr<Array> int16_values;

            void SetUp() override {
                string_values = assert_array_from_json(utf8(), R"(["Hello", "World", null])");
                int32_values = assert_array_from_json(int32(), "[1, 20, 3]");
                int16_values = assert_array_from_json(int16(), "[10, 2, 30]");
            }

            static std::shared_ptr<Array> Offsets(std::string_view json) {
                return assert_array_from_json(int32(), json);
            }

            static std::shared_ptr<Array> Sizes(std::string_view json) {
                return assert_array_from_json(int32(), json);
            }
        };

    }  // namespace

    TEST_F(TestListViewArray, make_array) {
        ASSERT_OK_AND_ASSIGN(auto list_view_array,
                             ListViewArray::from_arrays(*Offsets("[0, 0, 1, 2]"),
                                                       *Sizes("[2, 1, 1, 1]"), *string_values));
        auto array_data = list_view_array->data();
        auto new_array = make_array(array_data);
        ASSERT_ARRAYS_EQUAL(*new_array, *list_view_array);
        // Should be the exact same ArrayData object
        ASSERT_EQ(new_array->data(), array_data);
        ASSERT_NE(std::dynamic_pointer_cast<ListViewArray>(new_array), nullptr);
    }

    TEST_F(TestListViewArray, FromOffsetsAndSizes) {
        std::shared_ptr<ListViewArray> list_view_array;

        ASSERT_OK_AND_ASSIGN(list_view_array, ListViewArray::from_arrays(
                *Offsets("[0, 0, 1, 1000]"),
                *Sizes("[2, 1, 1, null]"), *int32_values));
        ASSERT_EQ(list_view_array->length(), 4);
        ASSERT_ARRAYS_EQUAL(*list_view_array->values(), *int32_values);
        ASSERT_EQ(list_view_array->offset(), 0);
        ASSERT_EQ(list_view_array->data()->get_null_count(), 1);
        ASSERT_EQ(list_view_array->data()->buffers.size(), 3);
    }

}  // namespace nebula
